package com.tanhua.dubbo.server.api;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.dubbo.server.config.HuanXinConfig;
import com.tanhua.dubbo.server.enums.HuanXinMessageType;
import com.tanhua.dubbo.server.mapper.HuanXinUserMapper;
import com.tanhua.dubbo.server.pojo.HuanXinUser;
import com.tanhua.dubbo.server.pojo.Users;
import com.tanhua.dubbo.server.service.RequestService;
import com.tanhua.dubbo.server.service.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @author feihao
 * @version 1.0
 * @date 2021/7/5 17:18
 */

@Slf4j
@Service(version = "1.0.0")
public class HuanXinApiImpl implements HuanXinApi {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private HuanXinConfig huanXinConfig;

    @Autowired
    private RequestService requestService;

    @Autowired
    private HuanXinUserMapper huanXinUserMapper;


    /**
     * 获取环信token:
     *
     * @return
     */
    @Override
    public String getToken() {
        return tokenService.getToken();
    }

    @Override
    public Boolean register(Long userId) {
        //注册的url:
        String tarUrl = huanXinConfig.getUrl()
                + huanXinConfig.getOrgName()
                + "/" + huanXinConfig.getAppName()
                + "/users";

        //封装HuanXinUser:
        HuanXinUser huanXinUser = new HuanXinUser();
        huanXinUser.setUsername("HX_" + userId);
        huanXinUser.setPassword(IdUtil.simpleUUID()); //随机生产密码
        huanXinUser.setNickname("Jack is NO." + userId);

        //执行请求：
        HttpResponse response = requestService.execute(tarUrl, JSONUtil.toJsonStr(Arrays.asList(huanXinUser)), Method.POST);
        //请求ok：
        if (response.isOk()) {
            //将环信user保存到mysql:
            huanXinUser.setUserId(userId);
            huanXinUser.setCreated(new Date());
            huanXinUser.setUpdated(new Date());
            try {
                huanXinUserMapper.insert(huanXinUser);
                return true;
            } catch (Exception e) {
                log.error("保存环信User失败！ userId :" + userId, e);
            }
        }
        return false;
    }


    @Override
    public HuanXinUser queryHuanXinUserByUserId(Long userId) {

        QueryWrapper<HuanXinUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);

        return huanXinUserMapper.selectOne(queryWrapper);

    }


    /**
     * 根据huanxinUserName查询huanxinuser:
     *
     * @param userName
     * @return
     */
    @Override
    public HuanXinUser queryHuanXinUserByUserName(String userName) {

        QueryWrapper<HuanXinUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", userName);
        return this.huanXinUserMapper.selectOne(wrapper);
    }


    /**
     * 添加好友关系至环信
     *
     * @param userId   自己用户的id
     * @param friendId 要添加的好友 id
     * @return
     */
    @Override
    public Boolean addFriends(Long userId, Long friendId) {

        String tagUrl = huanXinConfig.getUrl()
                + huanXinConfig.getOrgName() + "/"
                + huanXinConfig.getAppName() + "/users/HX_"
                + userId + "/contacts/users/HX_"
                + friendId;

        try {
            HttpResponse response = requestService.execute(tagUrl, null, Method.POST);
            if (response.isOk()) {
                return true;
            }
        } catch (Exception e) {
            log.error("添加好友失败~ userId:" + userId, "friendId:" + friendId, e);
        }
        //添加失败返回false：
        return false;
    }

    /**
     * 删除环信好友列表：
     *
     * @param userId   param friends
     * @param friendId
     * @return
     */
    @Override
    public Boolean removeFriends(Long userId, Long friendId) {

        String targetUrl = this.huanXinConfig.getUrl()
                + this.huanXinConfig.getOrgName() + "/"
                + this.huanXinConfig.getAppName() + "/users/HX_" +
                userId + "/contacts/users/HX_" + friendId;
        try {
            // 404 -> 对方未在环信注册
            return this.requestService.execute(targetUrl, null, Method.DELETE).isOk();
        } catch (Exception e) {
            log.error("删除好友失败！ userId:" + userId, "friendId :" + friendId, e);
        }

        // 添加失败
        return false;
    }


    /**
     * 通过环信admin发送消息：
     *
     * @param targetUserName     发送目标的用户名
     * @param huanXinMessageType 消息类型
     * @param msg
     * @return
     */
    @Override
    public Boolean sendMessageByAdmin(String targetUserName, HuanXinMessageType huanXinMessageType, String msg) {

        //构建发送短信的url:
        String targetUrl = this.huanXinConfig.getUrl()
                + this.huanXinConfig.getOrgName() + "/"
                + this.huanXinConfig.getAppName() + "/messages";


        try {
            //构建请求体：
            //{"target_type": "users","target": ["user2","user3"],"msg": {"type": "txt","msg": "testmessage"},"from": "user1"}
            String body = JSONUtil.createObj().set("target_type", "users")
                    .set("target", JSONUtil.createArray().set(targetUserName))
                    .set("msg", JSONUtil.createObj().set("type", huanXinMessageType.getType()).set("msg", msg)).toString();
            return requestService.execute(targetUrl, body, Method.POST).isOk();
        } catch (Exception e) {
            log.error("发送消息失败~ targetUserName = " + targetUserName + ", type = " + huanXinMessageType.getType() + ", msg = " + msg, e);
        }
        return false;
    }
}
